package org.linlinjava.litemall.wx.web;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import javax.validation.constraints.NotNull;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.linlinjava.litemall.core.system.SystemConfig;
import org.linlinjava.litemall.core.util.ResponseUtil;
import org.linlinjava.litemall.db.service.LitemallAdService;
import org.linlinjava.litemall.db.service.LitemallPosterService;
import org.linlinjava.litemall.wx.annotation.LoginUser;
import org.linlinjava.litemall.wx.service.HomeCacheManager;
import org.linlinjava.litemall.wx.service.WxPurchaseService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

/**
 * 首页服务
 */
@RestController
@RequestMapping("/wx/home")
@Validated
public class WxHomeController {
	private final Log logger = LogFactory.getLog(WxHomeController.class);

	@Autowired
	private LitemallAdService adService;

	@Autowired
	private LitemallPosterService posterService;

	@Autowired
	private WxPurchaseService wxPurchaseService;

	private final static ArrayBlockingQueue<Runnable> WORK_QUEUE = new ArrayBlockingQueue<>(9);

	private final static RejectedExecutionHandler HANDLER = new ThreadPoolExecutor.CallerRunsPolicy();

	private static ThreadPoolExecutor executorService = new ThreadPoolExecutor(9, 9, 1000, TimeUnit.MILLISECONDS,
			WORK_QUEUE, HANDLER);

	@GetMapping("/cache")
	public Object cache(@NotNull String key) {
		if (!key.equals("litemall_cache")) {
			return ResponseUtil.fail();
		}

		// 清除缓存
		HomeCacheManager.clearAll();
		return ResponseUtil.ok("缓存已清除");
	}

	/**
	 * 首页数据
	 * 
	 * @param userId 当用户已经登录时，非空。为登录状态为null
	 * @return 首页数据
	 */
	@GetMapping("/index")
	public Object index(@LoginUser Integer userId, @RequestParam(defaultValue = "") String searchValue) {
		// 优先从缓存中读取
		if (HomeCacheManager.hasData(HomeCacheManager.INDEX)) {
			return ResponseUtil.ok(HomeCacheManager.getCacheData(HomeCacheManager.INDEX));
		}
		Callable<List> bannerListCallable = () -> adService.queryIndex();
		Callable<List> purchaseListCallable = () -> wxPurchaseService.queryList(userId, 0, SystemConfig.getPurchaseLimit(), searchValue);

		FutureTask<List> bannerTask = new FutureTask<>(bannerListCallable);
		FutureTask<List> purchaseTask = new FutureTask<>(purchaseListCallable);

		executorService.submit(bannerTask);
		executorService.submit(purchaseTask);

		Map<String, Object> entity = new HashMap<>();
		try {
			entity.put("banner", bannerTask.get());
			entity.put("purchaseList", purchaseTask.get());
			entity.put("purchaseBg", SystemConfig.getPurchaseBg());
			// 缓存数据
			HomeCacheManager.loadData(HomeCacheManager.INDEX, entity);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return ResponseUtil.ok(entity);
	}
	
	@GetMapping("/poster")
	public Object poster(@LoginUser Integer userId, @RequestParam(defaultValue = "") String searchValue) {
		// 优先从缓存中读取
		if (HomeCacheManager.hasData(HomeCacheManager.POSTER)) {
			return ResponseUtil.ok(HomeCacheManager.getCacheData(HomeCacheManager.POSTER));
		}
		Callable<List> posterListCallable = () -> posterService.queryIndex();

		FutureTask<List> posterTask = new FutureTask<>(posterListCallable);

		executorService.submit(posterTask);

		Map<String, Object> entity = new HashMap<>();
		try {
			entity.put("poster", posterTask.get());
			// 缓存数据
			HomeCacheManager.loadData(HomeCacheManager.POSTER, entity);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return ResponseUtil.ok(entity);
	}

	/**
	 * 公司介绍信息
	 * 
	 * @return 公司介绍信息
	 */
	@GetMapping("/about")
	public Object about() {
		Map<String, Object> about = new HashMap<>();
		about.put("name", SystemConfig.getMallName());
		about.put("address", SystemConfig.getMallAddress());
		about.put("phone", SystemConfig.getMallPhone());
		about.put("qq", SystemConfig.getMallQQ());
		about.put("longitude", SystemConfig.getMallLongitude());
		about.put("latitude", SystemConfig.getMallLatitude());
		about.put("aboutInfoBg", SystemConfig.getAboutInfoBg());
		return ResponseUtil.ok(about);
	}
}